package autokeyboard.handler;

import java.io.File;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

import autokeyboard.data.DataAccess;
import autokeyboard.data.ExtensionFileFilter;
import autokeyboard.data.TableModel;
import autokeyboard.gui.AboutWindow;
import autokeyboard.gui.ControlsDialog;
import autokeyboard.gui.DialogTemp;
import autokeyboard.gui.HelpDialog;
import autokeyboard.gui.ImportFileDialog;
import autokeyboard.gui.KeyStrokeDialog;
import autokeyboard.gui.StartOptionDialog;
import autokeyboard.gui.TablePanel;

/**
 * This class is contains all Event in soft
 * 
 * @author HoldTheHand
 */
public class ShowDialogEvent
{
	private JFileChooser		chooser			= new JFileChooser();
	public static String		previousPath	= System.getProperty("user.dir");
	private String				filePath		= "";
	public static String		fileName		= "";
	private JTable				table;
	private ArrayList<Object[]>	listObject;
	private DataAccess			dataAccess		= new DataAccess();
	private TableModel			model			= new TableModel();
	private boolean				isSavePressed	= false;

	public void setTableAndList(JTable table, ArrayList<Object[]> listObject)
	{
		this.table = table;
		this.listObject = listObject;
	}

	public String getFileName()
	{
		return this.filePath;
	}

	public void showHelpDialog(JFrame frame)
	{
		new HelpDialog(frame).setVisible(true);
	}

	public void showAboutWindow(JFrame frame)
	{
		DialogTemp dlg = new DialogTemp(frame);
		AboutWindow aboutWindow = new AboutWindow(dlg);
		aboutWindow.setVisible(true);
		dlg.setVisible(true);
		aboutWindow.requestFocus();
	}

	public StartOptionDialog showStartOptionDialog(JFrame frame)
	{
		StartOptionDialog startDialog = new StartOptionDialog(frame);
		startDialog.setVisible(true);
		return startDialog;
	}

	/**
	 * This method will show open dialog
	 */
	public void showOpenDialog(JFrame frame)
	{
		chooser = new JFileChooser();
		if (!TablePanel.isChanged)
		{
			openNormal(frame);
		}
		else
		{
			int choice = JOptionPane.showConfirmDialog(frame, "Your current list key is changed. Do you wanna save it?", "Message", JOptionPane.YES_NO_CANCEL_OPTION);
			if (choice == JOptionPane.YES_OPTION)
			{
				showSaveDialog(frame);
				if (isSavePressed)
				{
					openNormal(frame);
				}
			}
			else if (choice == JOptionPane.NO_OPTION)
			{
				openNormal(frame);
			}
		}
	}

	/**
	 * This method is main show open dialog. It will show openDialog and it also
	 * get data from file and then set it into your table and your listObject
	 * 
	 * @param frame
	 */
	private void openNormal(JFrame frame)
	{
		chooser.setCurrentDirectory(new File(previousPath));
		chooser.setAcceptAllFileFilterUsed(false);
		chooser.setFileFilter(new ExtensionFileFilter());
		int choice = chooser.showOpenDialog(frame);
		if (choice == JFileChooser.APPROVE_OPTION)
		{
			previousPath = chooser.getCurrentDirectory().toPath().toString();
			filePath = chooser.getSelectedFile().toPath().toString();
			fileName = chooser.getSelectedFile().getName();
			frame.setTitle("Auto Keyboard - " + fileName);
			StringTokenizer token = new StringTokenizer(dataAccess.readFile(filePath), "\n");
			storetToListObject(token);
			setDataToTable();
			isSavePressed = false;
			TablePanel.isChanged = false;
		}
	}

	/**
	 * This method will get all texts from token and convert that texts to
	 * listObject
	 * 
	 * @param token
	 */
	private void storetToListObject(StringTokenizer token)
	{
		while (listObject.size() != 0)
		{
			listObject.remove(0);
		}
		while (token.hasMoreTokens())
		{
			listObject.add(splitToken(token.nextToken()));
		}
	}

	/**
	 * This method will split text that get from token to 4 pieces and store it
	 * in a list
	 * 
	 * @param text
	 * @return object[]
	 */
	private Object[] splitToken(String text)
	{
		Object[] temp = new Object[4];
		String delim = "\t";
		StringTokenizer token = new StringTokenizer(text, delim);
		for (int i = 0; i < temp.length; i++)
		{
			temp[i] = token.nextToken();
		}
		return temp;
	}

	/**
	 * This method will show saveAs dialog if your file is new file.
	 * 
	 * @param frame
	 */
	public void showSaveDialog(JFrame frame)
	{
		if (fileName.equals(""))
		{
			showSaveAsDialog(frame);
		}
		else
		{
			dataAccess.writeFile(filePath, encryptText());
			isSavePressed = true;
			TablePanel.isChanged = false;
		}
	}

	/**
	 * This method will show saveAs dialog when called
	 * 
	 * @param frame
	 */
	public void showSaveAsDialog(JFrame frame)
	{
		chooser = new JFileChooser();
		chooser.setFileFilter(new ExtensionFileFilter());
		chooser.setAcceptAllFileFilterUsed(false);
		chooser.setCurrentDirectory(new File(previousPath));
		int choice = chooser.showSaveDialog(frame);
		if (choice == JFileChooser.APPROVE_OPTION)
		{
			previousPath = chooser.getCurrentDirectory().toPath().toString();
			String temp = chooser.getSelectedFile().toPath().toString();
			if (temp.endsWith(".atk".toLowerCase()))
			{
				filePath = chooser.getSelectedFile().toPath().toString();
				fileName = chooser.getSelectedFile().getName();
			}
			else
			{
				filePath = chooser.getSelectedFile().toPath().toString() + ".atk";
				fileName = chooser.getSelectedFile().getName() + ".atk";
			}
			frame.setTitle("Auto Keyboard - " + fileName);
			dataAccess.writeFile(filePath, encryptText());
			isSavePressed = true;
			TablePanel.isChanged = false;
		}
		else if (choice == JFileChooser.CANCEL_OPTION)
		{
			isSavePressed = false;
		}
	}

	/**
	 * This method will encrypt your item from your table before save it
	 * 
	 * @return encrypted document
	 */
	private String encryptText()
	{
		String temp = "";
		for (int i = 0; i < listObject.size(); i++)
		{
			Object[] objTemp = listObject.get(i);
			temp += objTemp[0].toString() + "\t" + objTemp[1].toString() + "\t" + objTemp[2].toString() + "\t" + objTemp[3].toString() + "\n";
		}
		return temp;
	}

	/**
	 * This method will ask you to save your file if your table is changed
	 * 
	 * @param frame
	 */
	public void exitAsking(JFrame frame)
	{
		if (TablePanel.isChanged)
		{
			int choice = JOptionPane.showConfirmDialog(frame, "Do you wanna save before exit!", "Message", JOptionPane.YES_NO_CANCEL_OPTION);
			if (choice == JOptionPane.YES_OPTION)
			{
				showSaveDialog(frame);
				System.exit(1);
			}
			else if (choice == JOptionPane.NO_OPTION)
			{
				System.exit(1);
			}
		}
		else if (!TablePanel.isChanged)
		{
			System.exit(0);
		}
	}

	/**
	 * This method will create new file and ask you to save your current table
	 * if your current table is changed.
	 * 
	 * @param frame
	 */
	public void newFileEvent(JFrame frame)
	{
		if (TablePanel.isChanged)
		{
			int choice = JOptionPane.showConfirmDialog(frame, "Your file has been changed. Do you wanna save it?", "Message", JOptionPane.YES_NO_CANCEL_OPTION);
			if (choice == JOptionPane.YES_OPTION)
			{
				showSaveDialog(frame);
				fileName = "";
				frame.setTitle("Auto Keyboard");
				while (listObject.size() != 0)
				{
					listObject.remove(0);
				}
				setDataToTable();
			}
			else if (choice == JOptionPane.NO_OPTION)
			{
				fileName = "";
				frame.setTitle("Auto Keyboard");
				while (listObject.size() != 0)
				{
					listObject.remove(0);
				}
				setDataToTable();
			}
		}
		else
		{
			fileName = "";
			frame.setTitle("Auto Keyboard");
			while (listObject.size() != 0)
			{
				listObject.remove(0);
			}
			setDataToTable();
		}
	}

	/**
	 * This method will show Controls Dialog
	 * 
	 * @param frame
	 */
	public void showControlsDialog(JFrame frame)
	{
		new ControlsDialog(frame).setVisible(true);
	}

	/**
	 * This method will show KeyStrokeDialog
	 * 
	 * @param frame
	 * @param keyStroke
	 * @param keyStrokeDelay
	 * @return keyStrokeDialog
	 */
	public KeyStrokeDialog showKeyStrokeDialog(JFrame frame, Object[] list)
	{
		KeyStrokeDialog keyStrokeDialog = new KeyStrokeDialog(frame, list);
		keyStrokeDialog.setVisible(true);
		return keyStrokeDialog;
	}

	/**
	 * This method will show Import file dialog
	 * 
	 * @param frame
	 * @param table
	 * @param listObject
	 */
	public void showImportDialog(JFrame frame, JTable table, ArrayList<Object[]> listObject)
	{
		new ImportFileDialog(frame, table, listObject).setVisible(true);
	}

	public void showOpenImport(JFrame frame)
	{
		chooser = new JFileChooser();
		chooser.setCurrentDirectory(new File(previousPath));
		int choice = chooser.showOpenDialog(frame);
		if (choice == JFileChooser.APPROVE_OPTION)
		{
			previousPath = chooser.getCurrentDirectory().toPath().toString();
			filePath = chooser.getSelectedFile().toPath().toString();
		}
	}

	/**
	 * This method will set your new table with your import text
	 * <p>
	 * It also fill data to your listObject
	 */
	private void setDataToTable()
	{
		Object[][] list = new Object[listObject.size()][];
		for (int i = 0; i < listObject.size(); i++)
		{
			list[i] = listObject.get(i);
		}
		TablePanel.rowCount = listObject.size();
		table.setModel(model.setNewModel(list));
		columnAlignment(JLabel.LEFT);
		if (listObject.size() == 0)
			TablePanel.isChanged = false;
		else TablePanel.isChanged = true;
	}

	/**
	 * This method will align your column in your table with your input
	 * alignment
	 * 
	 * @param alignment
	 */
	private void columnAlignment(int alignment)
	{
		DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer();
		cellRenderer.setHorizontalAlignment(alignment);
		table.getColumnModel().getColumn(0).setCellRenderer(cellRenderer);
		table.getColumnModel().getColumn(1).setCellRenderer(cellRenderer);
		table.getColumnModel().getColumn(2).setCellRenderer(cellRenderer);
		table.getColumnModel().getColumn(3).setCellRenderer(cellRenderer);
	}
}
